export default class Matrix {
  public matrix: Array<number> = [1, 0, 0, 1, 0, 0]
  public min = 0.3
  public max = 10
  constructor(matrix?: Array<number>) {
    this.matrix = matrix || this.matrix
  }
  public reset() {
    this.matrix = [1, 0, 0, 1, 0, 0]
  }
  public multiply(a: Array<number>, b: Array<number>) {
    return [
      a[0] * b[0] + a[2] * b[1],
      a[1] * b[0] + a[3] * b[1],
      a[0] * b[2] + a[2] * b[3],
      a[1] * b[2] + a[3] * b[3],
      a[0] * b[4] + a[2] * b[5] + a[4],
      a[1] * b[4] + a[3] * b[5] + a[5]
    ]
  }
  public transform(matrixs: Array<Array<number>>) {
    if (matrixs.length == 0 || this.matrix.length == 1) return this.matrix
    else {
      for (let i = 0; i < matrixs.length; i++) this.matrix = this.multiply(matrixs[i], this.matrix)
    }
    return this.matrix
  }
  public translateMatrix(x: number, y: number): Array<number> {
    return [1, 0, 0, 1, x, y]
  }
  public scaleMatrix(scaleX: number, scaleY: number): Array<number> {
    return [scaleX, 0, 0, scaleY, 0, 0]
  }
  public rotateMatrix(value: number) {
    const sinAngle = Math.sin(value)
    const cosAngle = Math.cos(value)
    return [cosAngle, sinAngle, -sinAngle, cosAngle, 0, 0]
  }
  public skewMatrix(skewX: number, skewY: number) {
    return [1, Math.tan(skewY), Math.tan(skewX), 1, 0, 0]
  }
  public translateTo(x: number, y: number): Array<number> {
    this.matrix = this.multiply(this.translateMatrix(x, y), this.matrix)
    return this.matrix
  }
  public scaleTo(scaleX: number, scaleY: number): Array<number> {
    this.matrix = this.multiply(this.scaleMatrix(scaleX, scaleY), this.matrix)
    return this.matrix
  }
  public scaleByPoint(scaleX: number, scaleY: number, x: number, y: number) {
    this.matrix = this.multiply(this.translateMatrix(-x, -y), this.matrix)
    this.matrix = this.multiply(this.scaleMatrix(scaleX, scaleY), this.matrix)
    this.matrix = this.multiply(this.translateMatrix(x, y), this.matrix)
  }
  public clone() {
    return new Matrix([...this.matrix])
  }
}
